home *** CD-ROM | disk | FTP | other *** search
/ Alles Voor Internet / Tout Pour Internet / alles voor internet.iso / MacInternet™ / Telnet / NCSA / tn3270 2.3d26 source / tn3270 / api.c < prev    next >
Text File  |  1991-06-12  |  31KB  |  1,401 lines

  1. /*
  2.  *  tn3270 for the Macintosh Source Code
  3.  *  Brown University Computing and Information Services
  4.  *  Version 2.3d21, January 17, 1991
  5.  *  Copyright (c) 1988, 1989, 1990, 1991 by Brown University and by
  6.  *  Peter John DiCamillo.
  7.  *
  8.  *  Permission is granted to any individual or institution to use, copy,
  9.  *  or redistribute the binary version of this software and its
  10.  *  documentation provided this notice and the copyright notices are
  11.  *  retained.  Permission is granted to any individual or non-profit
  12.  *  institution to use, copy, modify, or redistribute the source files
  13.  *  of this software provided this notice and the copyright notices are
  14.  *  retained.  This software may not be distributed for profit, either
  15.  *  in original form or in derivative works, nor can the source be
  16.  *  distributed to other than an individual or a non-profit institution.
  17.  *  Any  individual or group interested in seeing and/or using these
  18.  *  source files but who are prevented from doing so by the above
  19.  *  constraints should contact Don Wolfe, Assistant Vice-President for
  20.  *  Computer Systems at Brown University, (401) 863-7250, for possible
  21.  *  software licensing of the source developed at Brown.
  22.  *
  23.  *  Brown University and Peter John DiCamillo make no representations
  24.  *  about the suitability of this software for any purpose.
  25.  *
  26.  *  BROWN UNIVERSITY AND PETER JOHN DICAMILLO GIVE NO WARRANTY, EITHER
  27.  *  EXPRESS OR IMPLIED, FOR THE PROGRAM AND/OR DOCUMENTATION PROVIDED,
  28.  *  INCLUDING, WITHOUT LIMITATION, WARRANTY OF MERCHANTABILITY AND
  29.  *  WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE.
  30.  *
  31.  */
  32.  
  33. #define __SEG__ api
  34. #include "maclib.h"
  35. #include "termdef.h"
  36. #include "globals.h"
  37. #include "telnet.h"
  38. #include "sppc.h"
  39.  
  40. Handle rcvMessage, sndMessage;    /* handles to message buffers */
  41.  
  42. short fromrefnum;                /* data for last received message */
  43. unsigned short msgLength;
  44. unsigned long msgId, replyId;
  45. unsigned char sppc_sessname[8] = "GFTM1-1";
  46. unsigned char ppcsessname[] = "\ptn3270 #1 session 1";
  47. char apimsgkind;                /* 0 = PPC, 1 = SPPC */
  48. static unsigned long apimsgid = 0;
  49. long ppcsref;                    /* used by PPC instead of fromrefnum */
  50.  
  51. PPCParamBlockPtr newparamblock();
  52. clientinfo * newclientrec();
  53. datainfo * newdatablock();
  54. OSErr apisend();
  55.  
  56. extern char pend_conn;
  57. extern unsigned char tcphostname[];
  58. extern char servermode;            /* server mode active */
  59. extern char hisopts[];
  60. extern short maxoff;
  61. extern char serverflags;
  62.  
  63. apiregister(char session)        /* register our API */
  64. {
  65. sppcregister(session);                        /* SPPC driver */
  66. if (ppcavail) ppcregister(session);            /* PPC Toolbox */
  67. }
  68.  
  69. sppcregister(char session)
  70. {
  71. static unsigned char smgrname[] = "GFTM1";
  72. short i;
  73. OSErr rc;
  74.  
  75. if (session == 0) {            /* session manager registration */
  76.     smgrname[4] = '1';
  77.     sppc_sessname[4] = '1';
  78.     for (i=0; i < 8; i++) {
  79.         rc = SPPCRegister(smgrname, &smgrrefnum);
  80.         if (rc == noErr) {
  81.             smgr_sppc = 1;
  82.             break;
  83.             }
  84.         else {
  85.             smgrname[4]++;
  86.             sppc_sessname[4]++;
  87.             }
  88.         }
  89.     if (smgr_sppc) {
  90.         if (rcvMessage == 0) rcvMessage = NewHandle((Size)128);
  91.         if (sndMessage == 0) sndMessage = NewHandle((Size)128);
  92.         if ((rcvMessage == 0) || (sndMessage == 0)) {
  93.             apideregister(0);
  94.             stoperr(apisalrt);
  95.             }
  96.         }
  97.     else if (rc == dupFNErr) {
  98.         stoperr(apinalrt);            /* tell user about name problem */
  99.         }
  100.     }
  101. else if (smgr_sppc) {                /* session registration */
  102.     sppc_sessname[6] = '1';
  103.     for (i=0; i < 8; i++) {
  104.         rc = SPPCRegister(sppc_sessname, &sessrefnum);
  105.         if (rc == noErr) {
  106.             sess_sppc = 1;
  107.             break;
  108.             }
  109.         else {
  110.             sppc_sessname[6]++;
  111.             }
  112.         }
  113.     if (!sess_sppc) {
  114.         sessrefnum = 0;
  115.         stoperr(apinalrt);            /* tell user about name problem */
  116.         }
  117.     }
  118. }
  119.  
  120. ppcregister(char session)
  121. {
  122. static unsigned char smgrname[] = "\ptn3270 #1";
  123. short i;
  124. OSErr rc;
  125. PPCOpenPBRec openpb;
  126. PPCPortRec pr;
  127. PPCParamBlockPtr ipb;
  128. pascal void (*compproc)();
  129. pascal void smgrinformproc();
  130. pascal void sessinformproc();
  131.  
  132. if (session == 0) {            /* session manager registration */
  133.     smgrname[9] = '1';
  134.     ppcsessname[9] = '1';
  135.     for (i=0; i < 8; i++) {
  136.         memset(&pr, 0, sizeof(PPCPortRec));
  137.         memcpy(pr.name, smgrname, 10);
  138.         pr.portKindSelector = ppcByString;
  139.         memcpy(pr.u.portTypeStr, "\ptn3270 Session Manager", 23);
  140.  
  141.         memset(&openpb, 0, sizeof(PPCOpenPBRec));
  142.         openpb.serviceType = ppcServiceRealTime;
  143.         openpb.portName = ≺
  144.         openpb.locationName = 0;
  145.         openpb.networkVisible = true;
  146.  
  147.         rc = ppcsync(PPCOpen, &openpb);
  148.         if (rc == noErr) {
  149.             smgrppc = 1;
  150.             smgrpref = openpb.portRefNum;
  151.             break;
  152.             }
  153.         else {
  154.             smgrname[9]++;
  155.             ppcsessname[9]++;
  156.             }
  157.         }
  158.     if (smgrppc) {
  159.         if (rcvMessage == 0) rcvMessage = NewHandle((Size)128);
  160.         if (sndMessage == 0) sndMessage = NewHandle((Size)128);
  161.         /* issue Inform for our new port */
  162.         ipb = newparamblock();
  163.         if ((ipb == 0) || (rcvMessage == 0) || (sndMessage == 0)) {
  164.             stoperr(ppcopenalrt);
  165.             ppcderegister(0);
  166.             return;
  167.             }
  168.         memset(ipb, 0, sizeof(PPCParamBlockRec));
  169.         compproc = smgrinformproc;
  170.         ipb->informParam.ioCompletion = (PPCCompProcPtr)compproc;
  171.         ipb->informParam.portRefNum = smgrpref;
  172.         ipb->informParam.autoAccept = false;
  173.         rc = ppcasync(PPCInform, ipb);
  174.         if (rc != noErr) {
  175.             stoperr(ppcopenalrt);
  176.             ppcderegister(0);
  177.             }
  178.         }
  179.     else if (rc == -910) {
  180.         stoperr(ppcnamealrt);        /* tell user about name problem */
  181.         }
  182.     else {
  183.         stoperr(ppcopenalrt);        /* other problem */
  184.         }
  185.     }
  186. else if (smgrppc) {                /* session registration */
  187.     ppcsessname[19] = '1';
  188.     for (i=0; i < 8; i++) {
  189.         memset(&pr, 0, sizeof(PPCPortRec));
  190.         memcpy(pr.name, ppcsessname, 20);
  191.         pr.portKindSelector = ppcByString;
  192.         memcpy(pr.u.portTypeStr, "\ptn3270 Session", 15);
  193.  
  194.         memset(&openpb, 0, sizeof(PPCOpenPBRec));
  195.         openpb.serviceType = ppcServiceRealTime;
  196.         openpb.portName = ≺
  197.         openpb.locationName = 0;
  198.         openpb.networkVisible = true;
  199.  
  200.         rc = ppcsync(PPCOpen, &openpb);
  201.         if (rc == noErr) {
  202.             sessppc = 1;
  203.             sesspref = openpb.portRefNum;
  204.             break;
  205.             }
  206.         else {
  207.             ppcsessname[19]++;
  208.             }
  209.         }
  210.     if (sessppc) {
  211.         /* issue Inform for our new port */
  212.         ipb = newparamblock();
  213.         if (ipb == 0) {
  214.             stoperr(ppcnamealrt);
  215.             ppcderegister(1);
  216.             return;
  217.             }
  218.         memset(ipb, 0, sizeof(PPCParamBlockRec));
  219.         compproc = sessinformproc;
  220.         ipb->informParam.ioCompletion = (PPCCompProcPtr)compproc;
  221.         ipb->informParam.portRefNum = sesspref;
  222.         ipb->informParam.autoAccept = false;
  223.         rc = ppcasync(PPCInform, ipb);
  224.         if (rc != noErr) {
  225.             stoperr(ppcnamealrt);
  226.             ppcderegister(1);
  227.             }
  228.         }
  229.     else {
  230.         sesspref = 0;
  231.         stoperr(ppcnamealrt);        /* tell user about name problem */
  232.         }
  233.     }
  234. }
  235.  
  236. pascal void smgrinformproc(pb)
  237. PPCParamBlockPtr pb;
  238. {
  239. OSErr rc;
  240. pascal void (*compproc)();
  241. pascal void smgraccproc();
  242. pascal void disposproc();
  243. clientinfo * cip;
  244. PPCParamBlockPtr ipb;
  245.  
  246. if (pb->informParam.ioResult != noErr) {
  247.     disposparamblock(pb);
  248.     return;
  249.     }
  250. cip = newclientrec();
  251. if (cip == 0) {
  252.     compproc = disposproc;
  253.     pb->rejectParam.ioCompletion = compproc;
  254.     rc = ppcasync(PPCReject, pb);
  255.     }
  256. else {
  257.     cip->sessrefnum = pb->informParam.sessRefNum;
  258.     cip->userdata = pb->informParam.userData;
  259.     cip->servicetype = pb->informParam.serviceType;
  260.     cip->reqtype = pb->informParam.requestType;
  261.     cip->mykind = 0;    /* session manager */
  262.     compproc = smgraccproc;
  263.     pb->acceptParam.ioCompletion = compproc;
  264.     rc = ppcasync(PPCAccept, pb);
  265.     }
  266. ipb = newparamblock();
  267. if (ipb == 0) {
  268.     return;
  269.     }
  270. memset(ipb, 0, sizeof(PPCParamBlockRec));
  271. compproc = smgrinformproc;
  272. ipb->informParam.ioCompletion = (PPCCompProcPtr)compproc;
  273. ipb->informParam.portRefNum = smgrpref;
  274. ipb->informParam.autoAccept = false;
  275. rc = ppcasync(PPCInform, ipb);
  276. }
  277.  
  278. pascal void sessinformproc(pb)
  279. PPCParamBlockPtr pb;
  280. {
  281. OSErr rc;
  282. pascal void (*compproc)();
  283. pascal void sessaccproc();
  284. pascal void disposproc();
  285. clientinfo * cip;
  286. PPCParamBlockPtr ipb;
  287.  
  288. if (pb->informParam.ioResult != noErr) {
  289.     disposparamblock(pb);
  290.     return;
  291.     }
  292. cip = newclientrec();
  293. if (cip == 0) {
  294.     compproc = disposproc;
  295.     pb->rejectParam.ioCompletion = compproc;
  296.     rc = ppcasync(PPCReject, pb);
  297.     }
  298. else {
  299.     cip->sessrefnum = pb->informParam.sessRefNum;
  300.     cip->userdata = pb->informParam.userData;
  301.     cip->servicetype = pb->informParam.serviceType;
  302.     cip->reqtype = pb->informParam.requestType;
  303.     cip->mykind = 1;    /* session */
  304.     compproc = sessaccproc;
  305.     pb->acceptParam.ioCompletion = compproc;
  306.     rc = ppcasync(PPCAccept, pb);
  307.     }
  308. ipb = newparamblock();
  309. if (ipb == 0) {
  310.     return;
  311.     }
  312. memset(ipb, 0, sizeof(PPCParamBlockRec));
  313. compproc = sessinformproc;
  314. ipb->informParam.ioCompletion = (PPCCompProcPtr)compproc;
  315. ipb->informParam.portRefNum = sesspref;
  316. ipb->informParam.autoAccept = false;
  317. rc = ppcasync(PPCInform, ipb);
  318. }
  319.  
  320. pascal void smgraccproc(pb)
  321. PPCParamBlockPtr pb;
  322. {
  323. datainfo *dip;
  324. OSErr rc;
  325. pascal void (*compproc)();
  326. pascal void disposproc();
  327. pascal void smgrreadproc();
  328.  
  329. if (pb->acceptParam.ioResult != noErr) {
  330.     deletesession(pb->acceptParam.sessRefNum);
  331.     disposparamblock(pb);
  332.     return;
  333.     }
  334. dip = newdatablock();
  335. if (dip == 0) {
  336.     compproc = disposproc;
  337.     pb->endParam.ioCompletion = compproc;
  338.     rc = ppcasync(PPCEnd, pb);
  339.     deletesession(pb->acceptParam.sessRefNum);
  340.     return;
  341.     }
  342. memset(dip, 0, sizeof(datainfo));
  343. compproc = smgrreadproc;
  344. pb->readParam.ioCompletion = compproc;
  345. pb->readParam.bufferLength = 128;
  346. pb->readParam.bufferPtr = dip->msg;
  347. rc = ppcasync(PPCRead, pb);
  348. }
  349.  
  350. pascal void sessaccproc(pb)
  351. PPCParamBlockPtr pb;
  352. {
  353. datainfo *dip;
  354. OSErr rc;
  355. pascal void (*compproc)();
  356. pascal void disposproc();
  357. pascal void sessreadproc();
  358.  
  359. if (pb->acceptParam.ioResult != noErr) {
  360.     deletesession(pb->acceptParam.sessRefNum);
  361.     disposparamblock(pb);
  362.     return;
  363.     }
  364. dip = newdatablock();
  365. if (dip == 0) {
  366.     compproc = disposproc;
  367.     pb->endParam.ioCompletion = compproc;
  368.     rc = ppcasync(PPCEnd, pb);
  369.     deletesession(pb->acceptParam.sessRefNum);
  370.     return;
  371.     }
  372. memset(dip, 0, sizeof(datainfo));
  373. compproc = sessreadproc;
  374. pb->readParam.ioCompletion = compproc;
  375. pb->readParam.bufferLength = 128;
  376. pb->readParam.bufferPtr = dip->msg;
  377. rc = ppcasync(PPCRead, pb);
  378. }
  379.  
  380. pascal void disposproc(pb)
  381. PPCParamBlockPtr pb;
  382. {
  383. disposparamblock(pb);
  384. }
  385.  
  386. pascal void smgrreadproc(pb)
  387. PPCParamBlockPtr pb;
  388. {
  389. datainfo *dip;
  390. OSErr rc;
  391. pascal void (*compproc)();
  392. pascal void disposproc();
  393. unsigned char *s;
  394.  
  395. if (pb->readParam.ioResult != noErr) {
  396.     deletesession(pb->acceptParam.sessRefNum);
  397.     disposparamblock(pb);
  398.     return;
  399.     }
  400. s = (unsigned char *)pb->readParam.bufferPtr;
  401. s -= 24;
  402. dip = (datainfo *)s;
  403. dip->length = pb->readParam.actualLength;
  404. dip->userdata = pb->readParam.userData;
  405. dip->creator = pb->readParam.blockCreator;
  406. dip->type = pb->readParam.blockType;
  407. dip->sessrefnum = pb->readParam.sessRefNum;
  408. dip->more = pb->readParam.more;
  409. dip->incoming = 1;
  410. dip->mykind = 0;
  411. dip->spare = 0;
  412.  
  413. dip = newdatablock();
  414. if (dip == 0) {
  415.     compproc = disposproc;
  416.     pb->endParam.ioCompletion = compproc;
  417.     rc = ppcasync(PPCEnd, pb);
  418.     deletesession(pb->acceptParam.sessRefNum);
  419.     return;
  420.     }
  421. memset(dip, 0, sizeof(datainfo));
  422. compproc = smgrreadproc;
  423. pb->readParam.ioCompletion = compproc;
  424. pb->readParam.bufferLength = 128;
  425. pb->readParam.bufferPtr = dip->msg;
  426. rc = ppcasync(PPCRead, pb);
  427. }
  428.  
  429. pascal void sessreadproc(pb)
  430. PPCParamBlockPtr pb;
  431. {
  432. datainfo *dip;
  433. OSErr rc;
  434. pascal void (*compproc)();
  435. pascal void disposproc();
  436. unsigned char *s;
  437.  
  438. if (pb->readParam.ioResult != noErr) {
  439.     deletesession(pb->acceptParam.sessRefNum);
  440.     disposparamblock(pb);
  441.     return;
  442.     }
  443. s = (unsigned char *)pb->readParam.bufferPtr;
  444. s -= 24;
  445. dip = (datainfo *)s;
  446. dip->length = pb->readParam.actualLength;
  447. dip->userdata = pb->readParam.userData;
  448. dip->creator = pb->readParam.blockCreator;
  449. dip->type = pb->readParam.blockType;
  450. dip->sessrefnum = pb->readParam.sessRefNum;
  451. dip->more = pb->readParam.more;
  452. dip->incoming = 1;
  453. dip->mykind = 1;
  454. dip->spare = 0;
  455.  
  456. dip = newdatablock();
  457. if (dip == 0) {
  458.     compproc = disposproc;
  459.     pb->endParam.ioCompletion = compproc;
  460.     rc = ppcasync(PPCEnd, pb);
  461.     deletesession(pb->acceptParam.sessRefNum);
  462.     return;
  463.     }
  464. memset(dip, 0, sizeof(datainfo));
  465. compproc = sessreadproc;
  466. pb->readParam.ioCompletion = compproc;
  467. pb->readParam.bufferLength = 128;
  468. pb->readParam.bufferPtr = dip->msg;
  469. rc = ppcasync(PPCRead, pb);
  470. }
  471.  
  472. deletesession(refnum)
  473. long refnum;
  474. {
  475. clientrec *cp;
  476.  
  477. cp = (clientrec *)clientqueue.first;
  478. while (cp != 0) {
  479.     if (cp->header.inuse) {
  480.         if (cp->client.sessrefnum == refnum) {
  481.             disposclientrec(&(cp->client));
  482.             return;
  483.             }
  484.         }
  485.     cp = (clientrec *)cp->header.next;        
  486.     }
  487. }
  488.  
  489. apideregister(char session)            /* cancel API registration */
  490. {
  491. sppcderegister(session);            /* SPPC driver */
  492. ppcderegister(session);                /* PPC Toolbox */
  493. apiwritenotify = 0;
  494. }
  495.  
  496. sppcderegister(char session)
  497. {
  498. /* deregister session, if any */
  499. if (sess_sppc) {
  500.     SPPCDeRegister(sessrefnum);
  501.     sess_sppc = 0;
  502.     }    
  503.  
  504. /* return if just session wanted */
  505. if (session) return;
  506.  
  507. /* deregister session manager */
  508. if (smgr_sppc) {
  509.     SPPCDeRegister(smgrrefnum);
  510.     smgr_sppc = 0;
  511.     }
  512. }
  513.  
  514. ppcderegister(char session)
  515. {
  516. PPCClosePBRec closepb;
  517. OSErr rc;
  518.  
  519. /* deregister session, if any */
  520. if (sessppc) {
  521.     memset(&closepb, 0, sizeof(PPCClosePBRec));
  522.     closepb.portRefNum = sesspref;
  523.     rc = ppcsync(PPCClose, &closepb);
  524.     sessppc = 0;
  525.     }    
  526.  
  527. /* return if just session wanted */
  528. if (session) return;
  529.  
  530. /* deregister session manager */
  531. if (smgrppc) {
  532.     memset(&closepb, 0, sizeof(PPCClosePBRec));
  533.     closepb.portRefNum = smgrpref;
  534.     rc = ppcsync(PPCClose, &closepb);
  535.     smgrppc = 0;
  536.     }
  537. }
  538.  
  539. apinewmsg()
  540. {
  541. OSErr rc;
  542. datarec *dp;
  543.  
  544. if (smgr_sppc) {
  545.     apimsgkind = 1;
  546.     rc = SPPCGet(smgrrefnum, &fromrefnum, 0, rcvMessage, &msgLength,
  547.                 &msgId, &replyId);
  548.     if (rc == noErr) smgrmsg();
  549.     if (sess_sppc) {
  550.         rc = SPPCGet(sessrefnum, &fromrefnum, 0, rcvMessage, &msgLength,
  551.                 &msgId, &replyId);
  552.         if (rc == noErr) sessmsg();
  553.         }
  554.     }
  555.  
  556. if (ppcavail) {
  557.     apimsgkind = 0;
  558.     dp = (datarec *)dataqueue.first;
  559.     while (dp != 0) {
  560.         if (dp->header.inuse) {
  561.             if (dp->data.incoming) {
  562.                 ppcsref = dp->data.sessrefnum;
  563.                 memcpy(*rcvMessage, dp->data.msg, dp->data.length);
  564.                 msgLength = dp->data.length;
  565.                 msgId = dp->data.userdata;
  566.                 replyId = dp->data.creator;
  567.                 if (dp->data.mykind == 0) {
  568.                     smgrmsg();
  569.                     }
  570.                 else {
  571.                     sessmsg();
  572.                     }
  573.                 disposdatarec(&(dp->data));
  574.                 }
  575.             }
  576.         dp = (datarec *)dp->header.next;        
  577.         }
  578.     }
  579. }
  580.  
  581. smgrmsg()
  582. {
  583. short **msgh;
  584.  
  585. msgh = (short **)rcvMessage;
  586. if (msgLength < 2) {
  587.     senderr(smgrrefnum, badRequestLength);
  588.     return;
  589.     }
  590.  
  591. switch (**msgh) {
  592.     case GetIdRequestType:
  593.                 if (msgLength != sizeof(GetIdRequest)) {
  594.                     senderr(smgrrefnum, badRequestLength);
  595.                     return;
  596.                     }
  597.                 sendid();
  598.                 break;
  599.     case GetCapRequestType:
  600.                 if (msgLength != sizeof(GetCapRequest)) {
  601.                     senderr(smgrrefnum, badRequestLength);
  602.                     return;
  603.                     }
  604.                 sendcap();
  605.                 break;
  606.     case GetVersRequestType:
  607.                 if (msgLength != sizeof(GetVersRequest)) {
  608.                     senderr(smgrrefnum, badRequestLength);
  609.                     return;
  610.                     }
  611.                 sendvers();
  612.                 break;
  613.     case OpenRequestType:
  614.                 if (msgLength != sizeof(OpenRequest)) {
  615.                     senderr(smgrrefnum, badRequestLength);
  616.                     return;
  617.                     }
  618.                 apiopensess();
  619.                 break;
  620.     case GetConnStatusType:
  621.                 if (msgLength != sizeof(GetConnStatus)) {
  622.                     senderr(smgrrefnum, badRequestLength);
  623.                     return;
  624.                     }
  625.                 sendconnstat();
  626.                 break;
  627.     default:
  628.                 senderr(smgrrefnum, badMessageType);
  629.                 break;
  630.     }
  631. }
  632.  
  633. senderr(myref, code)
  634. short myref, code;
  635. {
  636. ErrorResponse er;
  637. OSErr rc;
  638. long respid;
  639.  
  640. er.msgtype = ErrorResponseType;
  641. er.code = code;
  642. memcpy(*sndMessage, &er, sizeof(ErrorResponse));
  643. rc = apisend(myref, fromrefnum, msgId, sndMessage, sizeof(ErrorResponse),
  644.              &respid);
  645. }
  646.  
  647. sendcap()
  648. {
  649. GetCapResponse gcr;
  650. OSErr rc;
  651. long respid;
  652.  
  653. gcr.msgtype = GetCapResponseType;
  654. getsesscount(&gcr.pendsessions, &gcr.currsessions);
  655. gcr.maxsessions = 1;
  656. gcr.numbformats = 1;
  657. gcr.sizeinfo[0].ptsize = 9;
  658. gcr.sizeinfo[0].rows = rowmax9;
  659. gcr.sizeinfo[0].cols = colmax9;
  660. if ((rowmax12 >= 24) && (colmax12 >= 80)) {
  661.     gcr.numbformats = 2;
  662.     gcr.sizeinfo[1].ptsize = 12;
  663.     gcr.sizeinfo[1].rows = rowmax12;
  664.     gcr.sizeinfo[1].cols = colmax12;
  665.     }
  666. memcpy(*sndMessage, &gcr, sizeof(GetCapResponse));
  667. rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage, 
  668.              sizeof(GetCapResponse), &respid);
  669. }
  670.  
  671. getsesscount(pend, curr)
  672. short *pend, *curr;
  673. {
  674. if (serflg && connflg) {
  675.     *pend = 0;
  676.     *curr = 0;
  677.     }
  678. else if (logon || (pend_conn == 3)) {
  679.     if (serflg && apiopenpend) {
  680.         *pend = 1;
  681.         *curr = 0;
  682.         }
  683.     else {
  684.         *pend = 0;
  685.         *curr = 1;
  686.         }
  687.     }
  688. else if (pend_conn > 0) {
  689.     *pend = 1;
  690.     *curr = 0;
  691.     }
  692. else {
  693.     *pend = 0;
  694.     *curr = 0;
  695.     }
  696. }
  697.  
  698. sendvers()
  699. {
  700. GetVersResponse gvr;
  701. OSErr rc;
  702. long respid;
  703. Handle version;
  704. Size vsize;
  705.  
  706. memset(&gvr, 0, sizeof(GetVersResponse));
  707. gvr.msgtype = GetVersResponseType;
  708. version = GetResource('vers', 1);
  709. if (version != 0) {
  710.     vsize = GetHandleSize(version);
  711.     if (vsize > 120) vsize = 120;
  712.     memcpy(gvr.versdata, *version, vsize);
  713.     }
  714. memcpy(*sndMessage, &gvr, vsize+8);
  715. rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage, vsize+8, &respid);
  716. }
  717.  
  718. sendid()
  719. {
  720. GetIdResponse gir;
  721. OSErr rc;
  722. long respid;
  723. unsigned char apName[256];
  724. short apRefNum;
  725. Handle apParam;
  726. short namelen;
  727.  
  728. memset(&gir, 0, sizeof(GetIdResponse));
  729. gir.msgtype = GetIdResponseType;
  730. gir.signature = 'GFTM';
  731. GetAppParms(apName, &apRefNum, &apParam);
  732. gir.refnum = apRefNum;
  733. namelen = strlen(apName);
  734. namelen++;
  735. if (namelen > 120) namelen = 120;
  736. memcpy(gir.appname, apName, namelen);
  737. memcpy(*sndMessage, &gir, namelen+12);
  738. rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage, namelen+12, &respid);
  739. }
  740.  
  741. apiopensess()
  742. {
  743. unsigned short len, pend, curr;
  744. char fmtok;
  745. OpenResponse or;
  746. OSErr rc;
  747. long respid;
  748.  
  749. /* check that a session can be opened now */
  750. getsesscount(&pend, &curr);
  751. if ((pend + curr) > 0) {
  752.     memset(&or, 0, sizeof(OpenResponse));
  753.     or.msgtype = OpenResponseType;
  754.     or.code = openNoSessions;
  755.     memcpy(*sndMessage, &or, sizeof(OpenResponse));
  756.     rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
  757.                  sizeof(OpenResponse), &respid);
  758.     return;
  759.     }
  760.  
  761. /* copy open session request data */
  762. memcpy(&apiopenreq, *rcvMessage, sizeof(OpenRequest));
  763.  
  764. /* copy host name */
  765. len = strlen(apiopenreq.hostname);
  766. if (len > 255) len = 255;
  767. memcpy(apihostname, apiopenreq.hostname, len+1);
  768. apihostname[len] = 0;
  769. apiopenreq.hostname = apihostname;
  770.  
  771. /* copy window name */
  772. len = strlen(apiopenreq.windowname);
  773. if (len > 127) len = 127;
  774. memcpy(apiwindowname, apiopenreq.windowname, len+1);
  775. apiwindowname[len] = 0;
  776. apiopenreq.windowname = apiwindowname;
  777.  
  778. /* copy request message information */
  779. apiopenrefnum = fromrefnum;
  780. apiopenmsgid = msgId;
  781. apiopenkind = apimsgkind;
  782. apiopensref = ppcsref;
  783.  
  784. /* check the requested screen sizes are valid */
  785. fmtok = 1;
  786. if (apiopenreq.dfltsize.rows != 24) fmtok = 0;
  787. if (apiopenreq.dfltsize.cols != 80) fmtok = 0;
  788. if (apiopenreq.dfltsize.ptsize == 12) {
  789.     if (rowmax12 < 24) fmtok = 0;
  790.     if (colmax12 < 80) fmtok = 0;
  791.     }
  792. else if (apiopenreq.dfltsize.ptsize != 9) fmtok = 0;
  793. if (apiopenreq.altsize.rows < 24) fmtok = 0;
  794. if (apiopenreq.altsize.cols < 80) fmtok = 0;
  795. if (apiopenreq.altsize.ptsize == 9) {
  796.     if (rowmax9 < apiopenreq.altsize.rows) fmtok = 0;
  797.     if (colmax9 < apiopenreq.altsize.cols) fmtok = 0;
  798.     }
  799. else if (apiopenreq.altsize.ptsize == 12) {
  800.     if (rowmax12 < apiopenreq.altsize.rows) fmtok = 0;
  801.     if (colmax12 < apiopenreq.altsize.cols) fmtok = 0;
  802.     }
  803. else fmtok = 0;
  804. if (fmtok == 0) {
  805.     apiopenerr(openFormatErr);
  806.     return;
  807.     }
  808.  
  809. apiopen = apiopenpend = 1;
  810.  
  811. if (serflg) serlgin();
  812. else if (tcpflg) tcplgin();
  813. else netlgin();
  814. }
  815.  
  816. apiopenerr(code)
  817. short code;
  818. {
  819. apiopen = 0;
  820. apiopenresp(code);
  821. }
  822.  
  823. apiopenresp(code)
  824. short code;
  825. {
  826. OpenResponse or;
  827. OSErr rc;
  828. long respid;
  829. short len;
  830.  
  831. memset(&or, 0, sizeof(OpenResponse));
  832. or.msgtype = OpenResponseType;
  833. or.code = code;
  834. if ((code == open3270Mode) || (code == openLineMode)) {
  835.     if (smgr_sppc) {
  836.         or.sppcrefnum = sessrefnum;
  837.         if (sppc_sessname != 0) {
  838.             len = strlen(sppc_sessname);
  839.             if (len > 8) len = 8;
  840.             memcpy(or.sppcname, sppc_sessname, len+1);
  841.             }
  842.         }
  843.     if (smgrppc) {
  844.         or.ppcportnum = sesspref;
  845.         if (ppcsessname != 0) {
  846.             p2cstr(ppcsessname);
  847.             len = strlen(ppcsessname);
  848.             if (len > 20) len = 20;
  849.             memcpy(or.ppcname, ppcsessname, len+1);
  850.             c2pstr(ppcsessname);
  851.             }
  852.         }
  853.     }
  854. memcpy(*sndMessage, &or, sizeof(OpenResponse));
  855.  
  856. /* restore message information */
  857. fromrefnum = apiopenrefnum;
  858. msgId = apiopenmsgid;
  859. apimsgkind = apiopenkind;
  860. ppcsref = apiopensref;
  861.  
  862. rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
  863.              sizeof(OpenResponse), &respid);
  864. apiopenpend = 0;
  865. }
  866.  
  867. sendconnstat()
  868. {
  869. GetConnResponse gcr;
  870. unsigned long openid;
  871. OSErr rc;
  872. long respid;
  873. short len;
  874. short getconnstat();
  875.  
  876. openid = (*((GetConnStatus **)rcvMessage))->openid;
  877. memset(&gcr, 0, sizeof(GetConnResponse));
  878. gcr.msgtype = GetConnResponseType;
  879. if (apiopen) gcr.openid = apiopenmsgid;
  880. else gcr.openid = 0;
  881. gcr.statuscode = getconnstat(openid);
  882. memcpy(*sndMessage, &gcr, sizeof(GetConnResponse));
  883. rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
  884.              sizeof(GetConnResponse), &respid);
  885. }
  886.  
  887. short getconnstat(openid)
  888. unsigned long openid;
  889. {
  890. if (apiopen == 0) return(openBadId);
  891. if (openid != apiopenmsgid) return(openBadId);
  892. if (apiopenpend == 0) {
  893.     if (logon) return(open3270Mode);
  894.     else return(openLineMode);
  895.     }
  896.  
  897. if (serflg) return(openConnPending);
  898.  
  899. switch(pend_conn) {
  900.     case 1:
  901.             return(openResPending);
  902.             break;
  903.     case 2:
  904.             return(openConnPending);
  905.             break;
  906.     case 3:
  907.             return(openNegOptions);
  908.             break;
  909.     default:
  910.             return(noError);
  911.             break;
  912.     }
  913. }
  914.  
  915. OSErr apisend(short myRefNum, short toRefNum, 
  916.               unsigned long replyId, Handle theMessage,
  917.               unsigned short msgLength, unsigned long *msgId)
  918. {
  919. PPCParamBlockPtr wbp;
  920. datainfo *dp;
  921. pascal void (*compproc)();
  922. pascal void writeproc();
  923.  
  924. if (apimsgkind == 1) {
  925.     return(SPPCSend(myRefNum, toRefNum, replyId, theMessage,
  926.             msgLength, msgId));
  927.     }
  928. else {
  929.     wbp = newparamblock();
  930.     if (wbp == 0) {
  931.         return(mFulErr);
  932.         }
  933.     dp = newdatablock();
  934.     if (dp == 0) {
  935.         disposparamblock(wbp);
  936.         return(mFulErr);
  937.         }
  938.     memset(wbp, 0, sizeof(PPCParamBlockRec));
  939.     compproc = writeproc;
  940.     wbp->writeParam.ioCompletion = compproc;
  941.     wbp->writeParam.sessRefNum = ppcsref;
  942.     wbp->writeParam.bufferLength = msgLength;
  943.     wbp->writeParam.bufferPtr = dp->msg;
  944.     apimsgid++;
  945.     wbp->writeParam.userData = apimsgid;
  946.     wbp->writeParam.blockCreator = replyId;
  947.     memset(dp, 0, sizeof(datainfo));
  948.     memcpy(dp->msg, *theMessage, msgLength);
  949.     return(ppcasync(PPCWrite, wbp));
  950.     }
  951. }
  952.  
  953. pascal void writeproc(pb)
  954. PPCParamBlockPtr pb;
  955. {
  956. unsigned char *s;
  957. datainfo * d;
  958.  
  959. s = (unsigned char *)pb->writeParam.bufferPtr;
  960. s -= 24;
  961. d = (datainfo *)s;
  962. disposdatarec(d);
  963. disposparamblock(pb);
  964. }
  965.  
  966. sessmsg()
  967. {
  968. short **msgh;
  969.  
  970. msgh = (short **)rcvMessage;
  971. if (msgLength < 2) {
  972.     senderr(sessrefnum, badRequestLength);
  973.     return;
  974.     }
  975.  
  976. switch (**msgh) {
  977.     case GetCharRequestType:
  978.                 if (msgLength != sizeof(GetCharRequest)) {
  979.                     senderr(sessrefnum, badRequestLength);
  980.                     return;
  981.                     }
  982.                 sendchar();
  983.                 break;
  984.     case CloseRequestType:
  985.                 if (msgLength != sizeof(CloseRequest)) {
  986.                     senderr(sessrefnum, badRequestLength);
  987.                     return;
  988.                     }
  989.                 sessclose();
  990.                 break;
  991.     case CloseNotifyRequestType:
  992.                 if (msgLength != sizeof(CloseNotifyRequest)) {
  993.                     senderr(sessrefnum, badRequestLength);
  994.                     return;
  995.                     }
  996.                 closenotify();
  997.                 break;
  998.     case GetBuffersRequestType:
  999.                 if (msgLength != sizeof(GetBuffersRequest)) {
  1000.                     senderr(sessrefnum, badRequestLength);
  1001.                     return;
  1002.                     }
  1003.                 getbuffers();
  1004.                 break;
  1005.     case WriteNotifyRequestType:
  1006.                 if (msgLength != sizeof(WriteNotifyRequest)) {
  1007.                     senderr(sessrefnum, badRequestLength);
  1008.                     return;
  1009.                     }
  1010.                 writenotify();
  1011.                 break;
  1012.     case SendDataRequestType:
  1013.                 if (msgLength != sizeof(SendDataRequest)) {
  1014.                     senderr(sessrefnum, badRequestLength);
  1015.                     return;
  1016.                     }
  1017.                 senddatareq();
  1018.                 break;
  1019.     case SendLocalRequestType:
  1020.                 if (msgLength != sizeof(SendLocalRequest)) {
  1021.                     senderr(sessrefnum, badRequestLength);
  1022.                     return;
  1023.                     }
  1024.                 sendlocal();
  1025.                 break;
  1026.     default:
  1027.                 senderr(sessrefnum, badMessageType);
  1028.                 break;
  1029.     }
  1030. }
  1031.  
  1032. sendchar()
  1033. {
  1034. GetCharResponse gcr;
  1035. OSErr rc;
  1036. long respid;
  1037. unsigned char *dest, *s;
  1038. short len, conn;
  1039.  
  1040. memset(&gcr, 0, sizeof(GetCharResponse));
  1041. gcr.msgtype = GetCharResponseType;
  1042. dest = (*((GetCharRequest **)rcvMessage))->hostname;
  1043. if (dest != 0) {
  1044.     if (tcpflg) {
  1045.         s = tcphostname;
  1046.         }
  1047.     else {
  1048.         s = cshostname;
  1049.         }
  1050.     len = strlen(s);
  1051.     if (len > 255) len = 255;
  1052.     memcpy(dest, s, len+1);
  1053.     }
  1054. dest = (*((GetCharRequest **)rcvMessage))->windowname;
  1055. if (dest != 0) {
  1056.     if (apiopen) {
  1057.         s = apiwindowname;
  1058.         }
  1059.     else {
  1060.         s = wtitle;
  1061.         }
  1062.     len = strlen(s);
  1063.     if (len > 127) len = 127;
  1064.     memcpy(dest, s, len+1);
  1065.     }
  1066. gcr.dfltsize.ptsize = ses_dfltptsize;
  1067. gcr.dfltsize.rows = 24;
  1068. gcr.dfltsize.cols = 80;
  1069. gcr.altsize.ptsize = ses_altptsize;
  1070. gcr.altsize.rows = ses_altrows;
  1071. gcr.altsize.cols = ses_altcols;
  1072. gcr.linemode = (logon == 0);
  1073. if (apiopen) {
  1074.     gcr.hide = apiopenreq.hide;
  1075.     gcr.nowsf = apiopenreq.nowsf;
  1076.     gcr.noalert = apiopenreq.noalert;
  1077.     }
  1078. else {
  1079.     gcr.hide = gcr.noalert = 0;
  1080.     gcr.nowsf = (cs.ext3270 == 0);
  1081.     }
  1082. memcpy(*sndMessage, &gcr, sizeof(GetCharResponse));
  1083. rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
  1084.         sizeof(GetCharResponse), &respid);
  1085. }
  1086.  
  1087. sessclose()
  1088. {
  1089. CloseResponse cr;
  1090. OSErr rc;
  1091. long respid;
  1092.  
  1093. memset(&cr, 0, sizeof(CloseResponse));
  1094. cr.msgtype = CloseResponseType;
  1095. cr.code = noError;
  1096. memcpy(*sndMessage, &cr, sizeof(CloseResponse));
  1097. rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
  1098.         sizeof(CloseResponse), &respid);
  1099. closeresponse(closeAPI);
  1100. if (serflg) serlgout(0xe3);
  1101.     else if (tcpflg) tcplgout();
  1102.         else netlgout();
  1103. }
  1104.  
  1105. closenotify()
  1106. {
  1107. CloseNotifyResponse cnr;
  1108. OSErr rc;
  1109. long respid;
  1110.  
  1111. memset(&cnr, 0, sizeof(CloseNotifyResponse));
  1112. cnr.msgtype = CloseNotifyResponseType;
  1113. if ((*((CloseNotifyRequest **)rcvMessage))->notifyflag) {
  1114.     if (apiclosenotify) {
  1115.         cnr.code = closeNotifyActive;
  1116.         }
  1117.     else {
  1118.         cnr.code = noError;
  1119.         apiclosenotify = 1;
  1120.         /* copy request message information */
  1121.         apicloserefnum = fromrefnum;
  1122.         apiclosemsgid = msgId;
  1123.         apiclosekind = apimsgkind;
  1124.         apiclosesref = ppcsref;
  1125.         }
  1126.     }
  1127. else {
  1128.     apiclosenotify = 0;
  1129.     cnr.code = noError;
  1130.     }
  1131.  
  1132. memcpy(*sndMessage, &cnr, sizeof(CloseNotifyResponse));
  1133. rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
  1134.         sizeof(CloseNotifyResponse), &respid);
  1135. }
  1136.  
  1137. closeresponse(code)
  1138. short code;
  1139. {
  1140. CloseEventResponse cer;
  1141. OSErr rc;
  1142. long respid;
  1143.  
  1144. if (!apiclosenotify) return;
  1145.  
  1146. memset(&cer, 0, sizeof(CloseEventResponse));
  1147. cer.msgtype = CloseEventResponseType;
  1148. cer.code = code;
  1149.  
  1150. if (smgr_sppc) {
  1151.     cer.sppcrefnum = sessrefnum;
  1152.     }
  1153. if (smgrppc) {
  1154.     cer.ppcportnum = sesspref;
  1155.     }
  1156.  
  1157. memcpy(*sndMessage, &cer, sizeof(CloseEventResponse));
  1158.  
  1159. /* restore message information */
  1160. fromrefnum = apicloserefnum;
  1161. msgId = apiclosemsgid;
  1162. apimsgkind = apiclosekind;
  1163. ppcsref = apiclosesref;
  1164.  
  1165. rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
  1166.              sizeof(CloseEventResponse), &respid);
  1167. apiclosenotify = 0;
  1168. }
  1169.  
  1170. getbuffers()
  1171. {
  1172. GetBuffersResponse gbr;
  1173. OSErr rc;
  1174. long respid;
  1175.  
  1176. memset(&gbr, 0, sizeof(GetBuffersResponse));
  1177. gbr.msgtype = GetBuffersResponseType;
  1178. gbr.databuff = chrbuff;
  1179. gbr.attrbuff = atrbuff;
  1180. gbr.kblock = &kblock;
  1181. gbr.kblcode = &kblcode;
  1182. gbr.curadr = &curadr;
  1183. memcpy(*sndMessage, &gbr, sizeof(GetBuffersResponse));
  1184. rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
  1185.         sizeof(GetBuffersResponse), &respid);
  1186. }
  1187.  
  1188. writenotify()
  1189. {
  1190. WriteNotifyResponse wnr;
  1191. OSErr rc;
  1192. long respid;
  1193.  
  1194. memset(&wnr, 0, sizeof(WriteNotifyResponse));
  1195. wnr.msgtype = WriteNotifyResponseType;
  1196. if ((*((WriteNotifyRequest **)rcvMessage))->notifyflag) {
  1197.     if (apiwritenotify) {
  1198.         wnr.code = writeNotifyActive;
  1199.         }
  1200.     else {
  1201.         wnr.code = noError;
  1202.         apiwritenotify = 1;
  1203.         /* copy request message information */
  1204.         apiwriterefnum = fromrefnum;
  1205.         apiwritemsgid = msgId;
  1206.         apiwritekind = apimsgkind;
  1207.         apiwritesref = ppcsref;
  1208.         }
  1209.     }
  1210. else {
  1211.     apiwritenotify = 0;
  1212.     wnr.code = noError;
  1213.     }
  1214.  
  1215. memcpy(*sndMessage, &wnr, sizeof(WriteNotifyResponse));
  1216. rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
  1217.         sizeof(WriteNotifyResponse), &respid);
  1218. }
  1219.  
  1220. writeresponse(ccwop)
  1221. unsigned char ccwop;
  1222. {
  1223. WriteEventResponse wer;
  1224. OSErr rc;
  1225. long respid;
  1226.  
  1227. if (!apiwritenotify) return;
  1228.  
  1229. memset(&wer, 0, sizeof(WriteEventResponse));
  1230. wer.msgtype = WriteEventResponseType;
  1231. wer.ccwop = ccwop;
  1232.  
  1233. if (smgr_sppc) {
  1234.     wer.sppcrefnum = sessrefnum;
  1235.     }
  1236. if (smgrppc) {
  1237.     wer.ppcportnum = sesspref;
  1238.     }
  1239.  
  1240. memcpy(*sndMessage, &wer, sizeof(WriteEventResponse));
  1241.  
  1242. /* restore message information */
  1243. fromrefnum = apiwriterefnum;
  1244. msgId = apiwritemsgid;
  1245. apimsgkind = apiwritekind;
  1246. ppcsref = apiwritesref;
  1247.  
  1248. rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
  1249.              sizeof(WriteEventResponse), &respid);
  1250. }
  1251.  
  1252. senddatareq()
  1253. {
  1254. SendDataResponse sdr;
  1255. OSErr rc;
  1256. long respid;
  1257. unsigned short caddr;
  1258. short length;
  1259. unsigned char *s;
  1260. unsigned char aidcode;
  1261. short i;
  1262. char geflag;
  1263.  
  1264. memset(&sdr, 0, sizeof(SendDataResponse));
  1265. sdr.msgtype = SendDataResponseType;
  1266. length = (*((SendDataRequest **)rcvMessage))->length;
  1267. s = (*((SendDataRequest **)rcvMessage))->data;
  1268.  
  1269. if (connflg && serflg) {        /* serial connection mode */
  1270.     if (length > 0) {
  1271.         for (i=0; i < length; i++) {
  1272.             apisendser(s[i]);
  1273.             sdr.count++;
  1274.             }
  1275.         }
  1276.     }
  1277. else if (tcpflg && (pend_conn == 3)) {
  1278.     if (length > 0) {            /* 3270 line mode */
  1279.         if (servermode) {
  1280.             putsrv(s, length, 1);
  1281.             }
  1282.         else {
  1283.             if (!hisopts[TELOPT_ECHO]) {
  1284.                 putscr(s, length, 0);
  1285.                 }
  1286.             tcpwrite(s, length);
  1287.             }
  1288.         sdr.count = length;
  1289.         }
  1290.     }
  1291. else {                            /* 3270 session */
  1292.     caddr = (*((SendDataRequest **)rcvMessage))->curadr;
  1293.     aidcode = (*((SendDataRequest **)rcvMessage))->aidcode;
  1294.                                     /* check for fatal errors */
  1295.     if (kblock) {
  1296.         sdr.code = sendLocked;
  1297.         }
  1298.     else if ((caddr != 0xffff) && (caddr > maxoff)) {
  1299.         sdr.code = sendBadAddress;        
  1300.         }
  1301.                                     
  1302.     if (sdr.code == noError) {
  1303.                                     /* set cursor address */
  1304.         if (caddr != 0xffff) {
  1305.             curadr = caddr;
  1306.             newcur();
  1307.             }
  1308.                                     /* store data */
  1309.         if (length > 0) {
  1310.             geflag = 0;
  1311.             apikberr = 0;
  1312.             for (i=0; i < length; i++) {
  1313.                 if (s[i] == 0x08) {
  1314.                     geflag = 1;
  1315.                     }
  1316.                 else {
  1317.                     datakey(s[i], geflag);
  1318.                     geflag = 0;
  1319.                     if (apikberr) {
  1320.                         sdr.code = apikberr;
  1321.                         break;
  1322.                         }
  1323.                     else {
  1324.                         sdr.count++;
  1325.                         }
  1326.                     }
  1327.                 }
  1328.             }
  1329.                                     /* send AID */    
  1330.         if ((aidcode != 0) && (sdr.code == noError)) {
  1331.             apikberr = 0;
  1332.             attnkey(aidcode);
  1333.             sdr.code = apikberr;
  1334.             }
  1335.         }
  1336.     }
  1337. sdr.curadr = curadr;
  1338. memcpy(*sndMessage, &sdr, sizeof(SendDataResponse));
  1339. rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
  1340.         sizeof(SendDataResponse), &respid);
  1341. }
  1342.  
  1343. apisendser(c)
  1344. unsigned char c;
  1345. {
  1346. if (c == 0x12) {
  1347.     serverflags = 0x01;
  1348.     srvswitch();
  1349.     }
  1350. else {
  1351.     if (servermode) {
  1352.         putsrv(&c, 1, 1);
  1353.         }
  1354.     else {
  1355.         mout(c);
  1356.         }
  1357.     }
  1358. }
  1359.  
  1360. sendlocal()
  1361. {
  1362. SendLocalResponse slr;
  1363. OSErr rc;
  1364. long respid;
  1365. unsigned short caddr;
  1366. short length;
  1367. unsigned char *s;
  1368. short i;
  1369.  
  1370. memset(&slr, 0, sizeof(SendLocalResponse));
  1371. slr.msgtype = SendLocalResponseType;
  1372. length = (*((SendLocalRequest **)rcvMessage))->length;
  1373. s = (*((SendLocalRequest **)rcvMessage))->data;
  1374. if (length > 0) {
  1375.                                     /* check for fatal errors */
  1376.     if (kblock) {
  1377.         if (s[0] != 13) {
  1378.             slr.code = sendLocked;
  1379.             }
  1380.         }
  1381.     if (slr.code == noError) {
  1382.                                     /* execute operations */
  1383.         apikberr = 0;
  1384.         for (i=0; i < length; i++) {
  1385.             funckey(s[i]);
  1386.             if (apikberr) {
  1387.                 slr.code = apikberr;
  1388.                 break;
  1389.                 }
  1390.             else {
  1391.                 slr.count++;
  1392.                 }
  1393.             }
  1394.         }
  1395.     }
  1396. slr.curadr = curadr;
  1397. memcpy(*sndMessage, &slr, sizeof(SendLocalResponse));
  1398. rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
  1399.         sizeof(SendLocalResponse), &respid);
  1400. }
  1401.